package Genericity_etc;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author Jimmy Zhan WORKSTATION
 * @date 2023/3/24 17:48
 * 说明：通配符
 */

/**
 * 测试：通配符?的使用
 */
public class WildcardCharacterTest {
    @Test
    public void test1(){
        List<?> list = null;
        List<Object> list1 = null;
        List<String> list2 = null;

        list = list1;
        list = list2;

        method(list1);
        method(list2);
    }

    public void method(List<?> list){
        // 只能读，不能写
//        for (Object obj: list) {
//            System.out.println(obj);
//        }
        Iterator<?> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }

    @Test
    public void test2() {
        List<?> list = null;
        List<String> list1 = new ArrayList<>();
        list1.add("AA");

        list = list1;

        // 读取数据（以集合为例）
        // ?，不确定类型，但是一定是一个引用类型，所以返回值类型为 Object.
        Object o = list.get(0);
        System.out.println(o);

        // 写入数据（以集合为例），除了null可以写入以外，其他均不可写入，因为不知道是什么类型
//        list.add("BB");
        list.add(null);
    }

    /**
     * 测试：有限制条件的通配符的使用
     * ? extends A:
     * ? super A:
     *
     *
     * 举例：
     * <? extends Number> (无穷小 , Number] 只允许泛型为Number及Number子类的引用调用
     * <? super Number> [Number , 无穷大) 只允许泛型为Number及Number父类的引用调用
     * <? extends Comparable> 只允许泛型为实现Comparable接口的实现类的引用调用
     */
    @Test
    public void test3() {
//        List<? extends Father> list = null;
        List<? super Father> list = null;
        List<Object> list1 = null;
        List<Father> list2 = null;
        List<Son> list3 = null;

        list = list1;
        list = list2;
//        list = list3;
    }

    /**
     * 针对于  ? extends A: 的读写
     * 读取数据：OK
     * 写数据：不允许，因为extends(-∞, Father]，没有下界
     * add一个对象，总能找到一个该对象的子类作为通配符的泛型，相当于父类对象赋值给子类，所以不OK
     */
    @Test
    public void test4() {
        List<? extends Father> list = null;
        List<Father> list1 = new ArrayList<>();

        list1.add(new Father());

        list = list1;

        // 读取数据：OK
        Father father = list.get(0);

        // 写数据：不允许
        list.add(null);
//        list.add(new Father());
//        list.add(new Son());
    }

    /**
     * 针对于  ? super A: 的读写
     * 读取数据：OK
     * 写数据：OK
     * super ---> [Father, +∞)
     * Father是下界，但是new其子类Son的对象也是可以的，因为所有的子类都可以多态给Father类
     * 不会出现父类对象赋值给子类对象的情况
     */
    @Test
    public void test5() {
        List<? super Father> list = null;
        List<Father> list1 = new ArrayList<>();

        list1.add(new Father());

        list = list1;

        // 读取数据：OK
        Object object = list.get(0);

        // 写数据：OK
        list.add(null);
//        list.add(new Object());
        list.add(new Father());
        list.add(new Son());
    }
}
